package com.dms.shanshan.core;

import com.dms.shanshan.core.Annotation.Autowired;
import com.dms.shanshan.core.Annotation.Component;
import com.dms.shanshan.core.Annotation.Controller;
import com.dms.shanshan.core.Annotation.RequestMapping;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class BeanFactory {
    private Map<String, Object> beansMap=new HashMap<String, Object>();
    //路径与方法的映射
    private Map<String, Method> requestMappingMethods = new HashMap<>();


    public BeanFactory(String basePackage) throws InstantiationException, IllegalAccessException {
        scanBean(basePackage);
        injectDependcy();
        registerController();
    }
    //扫描包路径下的所有类的方法:scanBean
    public void scanBean(String basePackage){
        //baserPackage:包路径 把包路径替换为文件路径
        String path = basePackage.replace(".", "/");
        URL url=this.getClass().getClassLoader().getResource(path);
        //获取资源url
        if (url == null) {
            throw new RuntimeException("Package not found: " + basePackage);
        }
        File dir=new File(url.getFile());
        for (File file:dir.listFiles()){
            if (file.isDirectory()){
                scanBean(basePackage+"."+file.getName());
            } else if (file.getName().endsWith(".class")) {
                String className=basePackage+"."+file.getName().replace(".class", "");
                try{
                    //反射创建类
                    Class<?> clazz=Class.forName(className);
                    //判断是否有component注解
                    if (clazz.isAnnotationPresent(Component.class)||clazz.isAnnotationPresent(Controller.class)){
                        Object instance=clazz.getDeclaredConstructor().newInstance();
                        //默认无参构造对象
                        beansMap.put(clazz.getSimpleName(), instance);
                    }
                }catch (Exception e){
                    System.out.println("出现错误 反射这边");
                }
            }
        }
    }
    //依赖注入的方法:injectDependcy
    public void injectDependcy(){
        //扫描所有bean
        for (Object bean:beansMap.values()){
            //扫描所有bean的字段
            for (Field field:bean.getClass().getDeclaredFields()){
                if (field.isAnnotationPresent(Autowired.class)){
                    //获取字段类型
                    Class<?> fieldType=field.getType();
                    //从beanMap中获取依赖的bean
                    Object dependencyBean=beansMap.get(fieldType.getSimpleName());
                    if(dependencyBean!=null){
                        try{
                            //允许访问私有
                            field.setAccessible(true);
                            //将字段赋值
                            field.set(bean, dependencyBean);
                        }catch (Exception e){
                            System.out.println("出现错误");
                        }
                    }
                }

            }
        }

    }
    //注册控制器的方法:registerController
    private void registerController() throws InstantiationException, IllegalAccessException {
        for (Object bean:beansMap.values()){
            Class<?> clazz = bean.getClass();
            if (clazz.isAnnotationPresent(Controller.class)){
                String basePath="";
                if (clazz.isAnnotationPresent(RequestMapping.class)){
                    RequestMapping requestMapping=clazz.getAnnotation(RequestMapping.class);
                    basePath=requestMapping.value();
                }
                for (Method method:clazz.getDeclaredMethods()){
                    if (method.isAnnotationPresent(RequestMapping.class)){
                        RequestMapping methodsMapping=method.getAnnotation(RequestMapping.class);
                        String fullPath=basePath+methodsMapping.value();
                        requestMappingMethods.put(fullPath, method);
                        System.out.println("Mapped path: " + fullPath + " -> " + method.getName());
                    }
                }

            }
        }

    }
    public Object handleRequest(String path){
        //根据fullPath获得方法
        Method method=requestMappingMethods.get(path);
        if (method!=null){
            try {
                Object Controller=beansMap.get(method.getDeclaringClass().getSimpleName());
                return method.invoke(Controller);
            }catch (Exception e){
                System.out.println("出现错误");
            }
        }
        return "404 not found";
    }
}
